/*
 * Copyright (C) 2009 University of Washington
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
 * in compliance with the License. You may obtain a copy of the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software distributed under the License
 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 * or implied. See the License for the specific language governing permissions and limitations under
 * the License.
 */
 
package org.refunite.tasks;

import org.odk.collect.android.database.FileDbAdapter;
import org.odk.collect.android.listeners.FormDownloaderListener;
import org.odk.collect.android.utilities.FileUtils;
import org.refunite.activities.DownloadLatestForm;
import org.refunite.exception.TechnicalException;
import org.refunite.ws.WebServiceProvider;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;


import android.database.Cursor;
import android.os.AsyncTask;

import java.io.File;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.StringBufferInputStream;
import java.net.MalformedURLException;
import java.net.SocketTimeoutException;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.HashMap;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

/**
 * Background task for downloading the latest Refugees form.
 * 
 * @author i035316
 */
public class DownloadFormTask extends
        AsyncTask<HashMap<String, String>, String, HashMap<String, String>> {

    

	// used to store form name if one errors
    public static final String DL_FORM = "dlform";

    // used to store error message if one occurs
    public static final String DL_ERROR_MSG = "dlerrormessage";

    // used to indicate that we tried to download forms. If it's not included we tried to download a
    // form list.
    public static final String DL_FORMS = "dlforms";
    private FormDownloaderListener mStateListener;


    @Override
    protected HashMap<String, String> doInBackground(HashMap<String, String>... values) {

    	FileDbAdapter fda = null;
        HashMap<String, String> result = new HashMap<String, String>();
        result.put(DL_FORMS, DL_FORMS); // indicate that we're trying to download forms.

    	if (values != null && values[0].containsKey(DownloadLatestForm.SERVER_URL)) {
         
            String serverURL = values[0].get(DownloadLatestForm.SERVER_URL);
        	

                try {
                    publishProgress("Refugees United Form", "1", "1");
                    String newForm = WebServiceProvider.callGetCurrentRegistrationFormWS(serverURL);
                    fda = new FileDbAdapter();
                    fda.open();

                	String path = FileUtils.FORMS_PATH + FileUtils.REFUNITE_FORM_FILENAME;
                    File f = new File(path);
                	//we always overwrite the file
                    FileWriter writer = new FileWriter(f, false);
                	writer.write(newForm);
                	writer.flush();
                	writer.close();
                	

                    // update forms database
                    if (fda != null) {
                        // addOrphanForms will remove duplicates, and add new forms to the database
                        fda.addOrphanForms();
                        fda.close();
                    }
                    
                } catch (TechnicalException se) {
                    se.printStackTrace();
                    result.put(DL_FORM, "Refugees United form");
                    result.put(DL_ERROR_MSG, "Cannot download latest version");
                } catch (Exception e) {
                    e.printStackTrace();
                    result.put(DL_FORM, "Refugees United form");
                    result.put(DL_ERROR_MSG, e.getLocalizedMessage());
                }
            }


            return result;
        }
        


//    private File downloadFile(String name, String url) throws IOException {
//        // create url
//        URL u = null;
//        File f = null;
//        try {
//            u = new URL(url);
//        } catch (MalformedURLException e) {
//            e.printStackTrace();
//            throw e;
//        }
//
//        try {
//            // prevent deadlock when connection is invalid
//            URLConnection c = u.openConnection();
//            c.setConnectTimeout(CONNECTION_TIMEOUT);
//            c.setReadTimeout(CONNECTION_TIMEOUT);
//
//            // write connection to file
//            InputStream is = c.getInputStream();
//
//            String path = FileUtils.FORMS_PATH + name;
//            int i = 2;
//            int slash = path.lastIndexOf("/") + 1;
//            int period = path.lastIndexOf(".") + 1;
//            String base = path.substring(0, slash - 1);
//            String filename = path.substring(slash, period - 1);
//            String ext = path.substring(period);
//            f = new File(path);
//            while (f.exists()) {
//                f = new File(base + "/" + filename + "_" + i + "." + ext);
//                i++;
//            }
//
//            OutputStream os = new FileOutputStream(f);
//            byte buf[] = new byte[1024];
//            int len;
//            while ((len = is.read(buf)) > 0) {
//                os.write(buf, 0, len);
//            }
//            os.flush();
//            os.close();
//            is.close();
//
//        } catch (IOException e) {
//            e.printStackTrace();
//            throw e;
//        }
//
//        return f;
//    }


    @Override
    protected void onPostExecute(HashMap<String, String> value) {
        synchronized (this) {
            if (mStateListener != null) {
                mStateListener.formDownloadingComplete(value);
            }
        }
    }


    @Override
    protected void onProgressUpdate(String... values) {
        synchronized (this) {
            if (mStateListener != null) {
                // update progress and total
                mStateListener.progressUpdate(values[0], new Integer(values[1]).intValue(),
                    new Integer(values[2]).intValue());
            }
        }

    }


    public void setDownloaderListener(FormDownloaderListener sl) {
        synchronized (this) {
            mStateListener = sl;
        }
    }
}
